unit dxDemoUtils;

{$I cxVer.inc}

interface

uses
  Windows, Classes, SysUtils, ShellAPI, dxCore, cxClasses, dxBar,
  cxLookAndFeels, cxLookAndFeelPainters, dxNavBar, dxNavBarConsts,
  dxSkinsForm, dxSkinsDefaultPainters, dxSkinsLookAndFeelPainter, dxSkinsStrs;

const
  dxStartURL = 'http://www.devexpress.com/';
  dxDownloadURL = 'Downloads';
  dxSupportURL = 'Support/Center';
  dxProductsURL = 'Products/VCL/';
  dxMyDXURL = 'ClientCenter';
  dxMegaDemoProductIndex: Integer = -1;

  // Products features relative paths
  dxBarsPath = 'ExBars/Features.xml';
  dxRibbonPath = 'ExBars/Ribbon.xml';
  dxDockingPath = 'ExBars/DockingLib.xml';
  dxDBTreeViewPath = 'ExDBTree/Features.xml';
  dxFlowChartPath = 'ExFlowChart';
  dxGridPath = 'ExQuantumGrid/index.xml';
  dxLayoutControlPath = 'ExLayoutControl/whatsnewv2.xml';
  dxLocalizerPath = 'Subscription/WhatsNewBuild40/index.xml#autolist1';
  dxMasterViewPath = 'ExMasterView';
  dxNavBarPath = 'ExNavBar/WhatsNewV2.xml';
  dxOrgChartPath = 'ExOrgChart';
  dxPivotGridPath = 'ExPivotGrid/Features.xml';
  dxPrintingSystemPath = 'ExPrintingSystem/whatsnewv4.xml';
  dxSchedulerPath = 'ExScheduler/WhatsNewV3.xml';
  dxSkinsPath = 'ExSkins';
  dxSpellCheckerPath = 'ExSpellChecker/whatsnewv2.xml';
  dxSpreadSheetPath = 'ExSpreadSheet';
  dxTreeListPath = 'ExQuantumTreeList';
  dxVerticalGridPath = 'ExVerticalGrid';

  // Products names
  dxBarsProductName = 'ExpressBars';
  dxRibbonProductName = 'ExpressRibbon';
  dxDockingProductName = 'ExpressDocking';
  dxDBTreeViewProductName = 'ExpressDBTreeView';
  dxFlowChartProductName = 'ExpressFlowChart';
  dxGridProductName = 'ExpressQuantumGrid';
  dxLayoutControlProductName = 'ExpressLayoutControl';
  dxLocalizerProductName = 'ExpressLocalizer';
  dxMasterViewProductName = 'ExpressMasterView';
  dxNavBarProductName = 'ExpressNavBar';
  dxOrgChartProductName = 'ExpressOrgChart';
  dxPivotGridProductName = 'ExpressPivotGrid';
  dxPrintingSystemProductName = 'ExpressPrintingSystem';
  dxSchedulerProductName = 'ExpressScheduler';
  dxSkinsProductName = 'ExpressSkinsLibrary';
  dxSpellCheckerProductName = 'ExpressSpellChecker';
  dxSpreadSheetProductName = 'ExpressSpreadSheet';
  dxTreeListProductName = 'ExpressQuantumTreeList';
  dxVerticalGridProductName = 'ExpressVertical';

  // Product indices
  dxBarsIndex =            0;
  dxRibbonIndex =          1;
  dxDockingIndex =         2;
  dxDBTreeViewIndex =      3;
  dxFlowChartIndex =       4;
  dxGridIndex =            5;
  dxLayoutControlIndex =   6;
  dxLocalizerIndex =       7;
  dxMasterViewIndex =      8;
  dxNavBarIndex =          9;
  dxOrgChartIndex =       10;
  dxPivotGridIndex =      11;
  dxPrintingSystemIndex = 12;
  dxSchedulerIndex =      13;
  dxSkinsIndex =          14;
  dxSpellCheckerIndex =   15;
  dxSpreadSheetIndex =    16;
  dxTreeListIndex =       17;
  dxVerticalGridIndex =   18;
  dxLastProductIndex = dxVerticalGridIndex;

  dxProductNames: array [0..dxLastProductIndex] of string = (
    dxBarsProductName, dxRibbonProductName, dxDockingProductName, dxDBTreeViewProductName,
    dxFlowChartProductName, dxGridProductName, dxLayoutControlProductName,
    dxLocalizerProductName, dxMasterViewProductName, dxNavBarProductName,
    dxOrgChartProductName, dxPivotGridProductName, dxPrintingSystemProductName,
    dxSchedulerProductName, dxSkinsProductName, dxSpellCheckerProductName,
    dxSpreadSheetProductName, dxTreeListProductName, dxVerticalGridProductName);

  dxProductRelativeURLs: array [0..dxLastProductIndex] of string = (
    dxBarsPath, dxRibbonPath, dxDockingPath, dxDBTreeViewPath, dxFlowChartPath,
    dxGridPath, dxLayoutControlPath, dxLocalizerPath, dxMasterViewPath, dxNavBarPath,
    dxOrgChartPath, dxPivotGridPath, dxPrintingSystemPath, dxSchedulerPath, dxSkinsPath,
    dxSpellCheckerPath, dxSpreadSheetPath, dxTreeListPath, dxVerticalGridPath);

type
  dxSitePage = (spFeatures, spDownloads, spSupport, spStart, spProducts, spMyDX);

procedure Browse(ASitePage: dxSitePage);
procedure CreateHelpMenuItems(ABarManager: TdxBarManager; AHelpSubItem: TdxBarSubItem);
procedure CreateSkinsMenuItems(ABarManager: TdxBarManager;
  AViewSubItem: TdxBarSubItem; ASkinController: TdxSkinController; ANavBar: TdxNavBar = nil);
procedure PopulateSkinNames(ASkinNames: TStrings);
procedure SetNavBarStyle(ANavBar: TdxNavBar; ASkinController: TdxSkinController);

implementation

type
  TdxBarMenuItemClickController = class
  protected
    procedure MenuItemClickHandler(Sender: TObject); virtual; abstract;
  end;

  TdxHelpMenuClickController = class(TdxBarMenuItemClickController)
  protected
    procedure MenuItemClickHandler(Sender: TObject); override;
  end;

  TdxSkinMenuClickController = class(TdxBarMenuItemClickController)
  private
    FSkinController: TdxSkinController;
    FNavBar: TdxNavBar;
  protected
    procedure MenuItemClickHandler(Sender: TObject); override;
  end;

var
  FSkinsBarMenuItems: TcxObjectList;
  FSkins: TStringList;
  FSkinResources: TStringList;
  FSkinClickController: TdxSkinMenuClickController;
  FHelpClickController: TdxHelpMenuClickController;
  dxMegaDemoFeaturesItemCaption: string = '&Features';

procedure Browse(ASitePage: dxSitePage);
var
  AURL: string;
begin
  case ASitePage of
    spFeatures: AURL := dxStartURL + dxProductsURL + dxProductRelativeURLs[dxMegaDemoProductIndex];
    spDownloads: AURL := dxStartURL + dxDownloadURL;
    spSupport: AURL := dxStartURL + dxSupportURL;
    spStart: AURL := dxStartURL;
    spProducts: AURL := dxStartURL + dxProductsURL;
    spMyDX: AURL := dxStartURL + dxMyDXURL;
  end;
  ShellExecute(0, 'OPEN', PChar(AURL), nil, nil, SW_SHOW);
end;

procedure CreateHelpMenuItems(ABarManager: TdxBarManager; AHelpSubItem: TdxBarSubItem);

  function AddButton(ASubItem: TdxBarSubItem; ACaption: string; ATag: Integer;
    AHasSeparator: Boolean = False): TdxBarButton;
  begin
    Result := ABarManager.AddButton;
    with Result do
    begin
      Caption := Acaption;
      OnClick := FHelpClickController.MenuItemClickHandler;
      Tag := ATag;
    end;
    ASubItem.ItemLinks.Add(Result).BeginGroup := AHasSeparator;
  end;

begin
  FHelpClickController := TdxHelpMenuClickController.Create;
  AddButton(AHelpSubItem, dxProductNames[dxMegaDemoProductIndex] + ' ' + dxMegaDemoFeaturesItemCaption, 0);
  AddButton(AHelpSubItem, 'Developer Express &Downloads', 1, True);
  AddButton(AHelpSubItem, 'Developer Express Support &Center', 2);
  AddButton(AHelpSubItem, 'Developer Express &Products', 4);
  AddButton(AHelpSubItem, 'Developer Express on the &Web', 5);
end;

procedure CreateSkinsMenuItems(ABarManager: TdxBarManager;
  AViewSubItem: TdxBarSubItem; ASkinController: TdxSkinController; ANavBar: TdxNavBar);

  function AddButton(ASubItem: TdxBarSubItem; ACaption: string; ATag: Integer): TdxBarButton;
  begin
    Result := ABarManager.AddButton;
    with Result do
    begin
      Caption := Acaption;
      OnClick := FSkinClickController.MenuItemClickHandler;
      ButtonStyle := bsChecked;
      GroupIndex := 6;
      Category := 3;
      Tag := ATag;
    end;
    ASubItem.ItemLinks.Add(Result);
  end;

var
  I: Integer;
  ASkinsSubItem: TdxBarSubItem;
  ASkinNames: TStringList;
begin
  FSkinClickController := TdxSkinMenuClickController.Create;
  FSkinClickController.FSkinController := ASkinController;
  FSkinClickController.FNavBar := ANavBar;
  FSkinsBarMenuItems := TcxObjectList.Create;

  AddButton(AViewSubItem, 'Flat', 0);
  AddButton(AViewSubItem, 'Standard', 1);
  AddButton(AViewSubItem, 'UltraFlat', 2);
  AddButton(AViewSubItem, 'Office11', 3);
  AddButton(AViewSubItem, 'Native', 4);

  ASkinsSubItem := ABarManager.AddSubItem;
  ASkinsSubItem.Caption := 'Skins';
  AViewSubItem.ItemLinks.Add(ASkinsSubItem);

  ASkinNames := TStringList.Create;
  try
    PopulateSkinNames(ASkinNames);
    if ASkinNames.Count > 0 then
      ASkinsSubItem.Visible := ivAlways;
    for I := 0 to ASkinNames.Count - 1 do
    begin
      if not SameText(ASkinNames[I], sdxDefaultUserSkinData) then
        AddButton(ASkinsSubItem, ASkinNames[I], 5 + I)
    end;
  finally
    ASkinNames.Free;
  end;

  ASkinsSubItem.ItemLinks[0].Item.Click;
end;

procedure PopulateSkinNames(ASkinNames: TStrings);
var
  I: Integer;
begin
  ASkinNames.Clear;
  dxSkinsPopulateSkinResources(hInstance, FSkinResources, FSkins);
  for I := 0 to FSkins.Count - 1 do
    ASkinNames.Add(FSkins[I]);
end;

procedure SetNavBarStyle(ANavBar: TdxNavBar; ASkinController: TdxSkinController);
begin
  if ASkinController.NativeStyle then
    if IsWinVista then
      ANavBar.View := dxNavBarVistaExplorerBarView
    else
      ANavBar.View := dxNavBarXPExplorerBarView
  else
    if ASkinController.UseSkins then
      ANavBar.View := dxNavBarSkinExplorerBarView
    else
      case ASkinController.Kind of
        lfStandard, lfFlat:
          ANavBar.View := dxNavBarExplorerBarView;
        lfUltraFlat:
          ANavBar.View := dxNavBarUltraFlatExplorerView;
        lfOffice11:
          ANavBar.View := dxNavBarOffice11ExplorerBarView;
      end;
end;

procedure DestroyMenuItems;
begin
  FreeAndNil(FSkinsBarMenuItems);
  FreeAndNil(FSkinClickController);
  FreeAndNil(FHelpClickController);
end;

{ TdxHelpMenuClickController }

procedure TdxHelpMenuClickController.MenuItemClickHandler(Sender: TObject);
begin
  Browse(dxSitePage(TComponent(Sender).Tag));
end;

{ TdxSkinMenuClickController }

procedure TdxSkinMenuClickController.MenuItemClickHandler(Sender: TObject);

  procedure SelectSkinByIndex(AIndex: Integer);
  var
    AStream: TStream;
    AInfo: TdxSkinLookAndFeelPainterInfo;
    APainter: TcxCustomLookAndFeelPainterClass;
  begin
    AStream := TResourceStream.Create(hInstance, FSkinResources[Integer(FSkins.Objects[AIndex])], PChar(sdxResourceType));
    try
      if GetExtendedStylePainters.GetPainterByName('UserSkin', APainter) and
        GetExtendedStylePainters.GetPainterData(APainter, AInfo) then
          AInfo.Skin.LoadFromStream(AStream);
    finally
      AStream.Free;
    end;
    FSkinController.SkinName := 'UserSkin';
    FSkinController.UseSkins := True;
    FSkinController.NativeStyle := False;
  end;

begin
  case TComponent(Sender).Tag of
    0..3:
      begin
        FSkinController.Kind := TcxLookAndFeelKind(TComponent(Sender).Tag);
        FSkinController.UseSkins := False;
        FSkinController.NativeStyle := False;
      end;
    4:
      begin
        FSkinController.UseSkins := False;
        FSkinController.NativeStyle := True;
      end;
  else
    SelectSkinByIndex(TComponent(Sender).Tag - 5);
  end;
  if FNavBar <> nil then
    SetNavBarStyle(FNavBar, FSkinController);
end;

initialization
  FSkins := TStringList.Create;
  FSkinResources := TStringList.Create;

finalization
  DestroyMenuItems;
  FreeAndNil(FSkinResources);
  FreeAndNil(FSkins);

end.
